﻿using Microsoft.Xaml.Behaviors;
using System.Windows;
using System.Windows.Media;

namespace Com.Lancetinc.Evs.Helpers
{
    /// <summary>
    /// 控制Grid中不同列的两个元素，使Top一致
    /// </summary>
    public class GridCtrlAlignTopBehavior : Behavior<FrameworkElement>
    {
        #region OffsetY

        public static readonly DependencyProperty OffsetYProperty =
            DependencyProperty.Register(nameof(OffsetY),
                typeof(double),
                typeof(GridCtrlAlignTopBehavior), new PropertyMetadata(0.0, (d, e) =>
                {
                    if (d is not GridCtrlAlignTopBehavior self) return;

                    self.OnOffsetYChanged();
                }));

        public double OffsetY
        {
            get => (double)GetValue(OffsetYProperty);
            set => SetValue(OffsetYProperty, value);
        }
        #endregion

        #region Target

        public static readonly DependencyProperty TargetProperty =
            DependencyProperty.Register(nameof(Target),
                typeof(FrameworkElement),
                typeof(GridCtrlAlignTopBehavior), new PropertyMetadata(null, (d, e) =>
                {
                    if (d is not GridCtrlAlignTopBehavior self) return;

                    self.OnTargetChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement);
                }));

        public FrameworkElement Target
        {
            get => (FrameworkElement)GetValue(TargetProperty);
            set => SetValue(TargetProperty, value);
        }
        #endregion

        private FrameworkElement _container;
        /// <inheritdoc />
        protected override void OnAttached()
        {
            base.OnAttached();

            _container = VisualTreeHelper.GetParent(AssociatedObject) as FrameworkElement;
            if (_container == null)
                return;

            _container.SizeChanged += Ele_SizeChanged;
            ResetMyPosition();
        }

        /// <inheritdoc />
        protected override void OnDetaching()
        {
            base.OnDetaching();
            if (_container == null)
                return;

            _container.SizeChanged -= Ele_SizeChanged;
        }

        private void Ele_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ResetMyPosition();
        }

        private void OnOffsetYChanged()
        {
            ResetMyPosition();
        }

        private void OnTargetChanged(FrameworkElement oldTarget, FrameworkElement newTarget)
        {
            if (oldTarget != null)
                oldTarget.SizeChanged -= Ele_SizeChanged;

            if (newTarget != null)
                newTarget.SizeChanged += Ele_SizeChanged;

            ResetMyPosition();
        }

        /// <summary>
        /// 重新设置当前元素的位置，使得上方位置保持一致
        /// </summary>
        private void ResetMyPosition()
        {
            if (AssociatedObject == null || _container == null || Target == null)
                return;

            // 目标控件相对父元素的位置
            var relativeLoc = Target.TranslatePoint(new Point(0, 0), _container);
            if (AssociatedObject.RenderTransform is not TranslateTransform transform)
            {
                transform = new TranslateTransform();
                AssociatedObject.RenderTransform = transform;
            }
            transform.Y = relativeLoc.Y + OffsetY;
        }
    }
}